#!/usr/local/bin/python3
# -*- coding: utf-8 -*-

"""
@File    : limit_interface.py
@Author  : Link
@Time    : 2022/11/6 12:46
@Mark    : 
"""
import csv
import time
from dataclasses import asdict
from typing import Dict, List

from BenchCore.stdf_interface.stdf_data_class import LimitClass, LimitTypes
from BenchUtils.log_utils import Print


class Limit:
    """
    从文件导入
    导入后的数据类型 dict ->
    {
        TEXT_TXT : PtrTuple,
        TEXT_TXT : PtrTuple,
        ...
    }
    """
    h_types = {LimitTypes.NA, LimitTypes.LE, LimitTypes.LT}
    l_types = {LimitTypes.NA, LimitTypes.GE, LimitTypes.GT}
    limit_dict: Dict[str, List[LimitClass]] = None

    cache_path = None
    cache_type = 0x0  # 0x1 -> csv, 0x2 -> tsv

    def __init__(self):
        self.limit_dict = {}
        self.cache_type = 0x0

    def print(self):
        for k, v in self.limit_dict.items():
            print("key: {}".format(k))
            print("value: {}".format(v))

    def reLoad(self):
        if self.cache_path == 0x0:
            return
        if self.cache_path is None:
            return
        Print.Warning("Limit Reload")
        self.limit_dict.clear()
        if self.cache_type == 0x1:
            self.read_csv_data(self.cache_path)
        if self.cache_path == 0x2:
            self.read_tsv_data(self.cache_path)
        limit_list = []
        for v in self.limit_dict.values():
            for each in v:
                limit_list.append(asdict(each))
        print(Print.PrintTableString(limit_list))

    def read_tsv_data(self, limit_path: str):
        self.limit_dict.clear()
        with open(limit_path, "r", encoding="utf-8") as f:
            text = f.read()
        lines = text.split('\n')
        for index, line in enumerate(lines):
            if index == 0:
                continue
            row = line.split("\t")
            if len(row) == 12:
                row.append("")
            if len(row) != 13:
                print("warning: row length != 13, may be is end line")
                continue
            l_limit = 0
            h_limit = 0
            if row[5] not in Limit.l_types:
                raise Exception("{} not in {}".format(row[5], Limit.l_types))
            if row[6] not in Limit.h_types:
                raise Exception("{} not in {}".format(row[6], Limit.h_types))
            if row[3] not in Limit.l_types:
                raise Exception("{} not in {}".format(row[5], Limit.l_types))
            if row[4] not in Limit.h_types:
                raise Exception("{} not in {}".format(row[6], Limit.h_types))
            if row[3] != LimitTypes.NA:
                # TODO: maybe raise
                l_limit = float(row[2])
            if row[4] != LimitTypes.NA:
                # TODO: maybe raise
                h_limit = float(row[5])
            temp_ptr = LimitClass(
                int(row[0]),  # TEST_NO
                row[1],
                l_limit,
                row[3],  # LO_TYPE
                row[4],  # HI_TYPE
                h_limit,
                row[6],
                int(row[7]),  # S_BIN
                row[8],
                int(row[9]),  # H_BIN
                row[10],
                int(row[11]),
                row[12],
            )
            if temp_ptr.TEST_TXT not in self.limit_dict:
                self.limit_dict[temp_ptr.TEST_TXT] = [temp_ptr]
            else:
                self.limit_dict[temp_ptr.TEST_TXT].append(temp_ptr)
        for key, value in self.limit_dict.items():
            self.limit_dict[key] = sorted(value, key=lambda x: x.SET_BIN_LEVEL, reverse=True)
        self.cache_path = limit_path
        self.cache_type = 0x2

    def read_csv_data(self, limit_path: str):
        self.limit_dict.clear()
        with open(limit_path, "r", encoding="utf-8") as f:
            csv_iter = csv.reader(f)
            next(csv_iter)
            for row in csv_iter:
                l_limit = 0
                h_limit = 0
                if row[3] not in Limit.l_types:
                    raise Exception("{} not in {}".format(row[5], Limit.l_types))
                if row[4] not in Limit.h_types:
                    raise Exception("{} not in {}".format(row[6], Limit.h_types))
                if row[3] != LimitTypes.NA:
                    # TODO: maybe raise
                    l_limit = float(row[2])
                if row[4] != LimitTypes.NA:
                    # TODO: maybe raise
                    h_limit = float(row[5])
                temp_ptr = LimitClass(
                    int(row[0]),  # TEST_NO
                    row[1],
                    l_limit,
                    row[3],  # LO_TYPE
                    row[4],  # HI_TYPE
                    h_limit,
                    row[6],
                    int(row[7]),  # S_BIN
                    row[8],
                    int(row[9]),  # H_BIN
                    row[10],
                    int(row[11]),
                    row[12],
                )
                if temp_ptr.TEST_TXT not in self.limit_dict:
                    self.limit_dict[temp_ptr.TEST_TXT] = [temp_ptr]
                else:
                    self.limit_dict[temp_ptr.TEST_TXT].append(temp_ptr)
        for key, value in self.limit_dict.items():
            self.limit_dict[key] = sorted(value, key=lambda x: x.SET_BIN_LEVEL, reverse=True)
        self.cache_path = limit_path
        self.cache_type = 0x1

    def read_dict_data(self, data: List[dict]):
        self.limit_dict.clear()
        try:
            for each in data:
                temp_ptr = LimitClass(
                    each.get("TEST_NUM", 0),  # TEST_NO
                    each["TEST_TEXT"],
                    each["L_LIMIT"],
                    each["L_LIMIT_TYPE"],  # LO_TYPE
                    each["H_LIMIT_TYPE"],  # HI_TYPE
                    each["H_LIMIT"],
                    each["UNITS"],
                    each["SOFT_BIN_LEVEL"],  # S_BIN
                    each["SOFT_BIN_NAME"],
                    each["HARD_BIN_LEVEL"],  # H_BIN
                    each["HARD_BIN_NAME"],
                    each["SET_BIN_LEVEL"],
                    each["SET_BIN_NAME"],
                )
                if temp_ptr.TEST_TXT not in self.limit_dict:
                    self.limit_dict[temp_ptr.TEST_TXT] = [temp_ptr]
                else:
                    self.limit_dict[temp_ptr.TEST_TXT].append(temp_ptr)
            for key, value in self.limit_dict.items():
                self.limit_dict[key] = sorted(value, key=lambda x: x.SET_BIN_LEVEL, reverse=True)
            self.cache_type = 0x0
        except Exception as err:
            Print.Error("read_dict_data:{}".format(err))
            return False
        return True

    def __getitem__(self, item):
        return self.limit_dict.get(item, None)


if __name__ == '__main__':
    limit = Limit()
    limit.read_csv_data(r"D:\GitCode\link_ate\DEMO_TEST\SLT1_4S_V1P04_20241105.csv")
    time.sleep(0.1)
    limit.print()
    time.sleep(0.1)
    limit.reLoad()
    time.sleep(0.1)
    limit.print()
    time.sleep(0.1)
